/**
  ******************************************************************************
  * @file    command_at.h
  * @author  ashuai0110
  * @version V2.3
  * @date    2024-07-01
  * @brief   AT指令交互
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __COMMAND_AT_H
#define __COMMAND_AT_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include "common_include.h"

/**
 * @addtogroup modules
 * @{
 */

/**
 * @defgroup command_at command_at
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/
/**
 * @defgroup command_at_global_macros command at global macros
 * @{
 */

#define CMD_AT_W_BUF_LEN                (48u) /*!< 发送缓冲区长度byte 用户按需修改 */
#define CMD_AT_R_BUF_LEN                (48u) /*!< 接收缓冲区长度byte 用户按需修改 */
#define CMD_AT_MARK_LEN                 (3u)  /*!< 前缀后缀数组长度byte 用户按需修改 */

/**
 * @defgroup command_at_reserve command at reserve
 * @{
 */
/* 影响cmd_at_process()函数最终保存在dataBuf的回复内容 保留:"AT+NAME=ashuai\r\n" 不保留:"NAME=ashuai" */
#define CMD_AT_NOT_RESERVE              (0u) /*!< 不保留前缀后缀 */
#define CMD_AT_RESERVE                  (1u) /*!< 保留前缀后缀 */
/**
 * @}
 */

/**
 * @defgroup command_at_way command at way
 * @{
 */
#define CMD_AT_WAY_SEARCH               (0u) /*!< 搜索前后缀的处理方式 */
#define CMD_AT_WAY_REC_FLAG             (1u) /*!< 外部接收标志的处理方式 */
/**
 * @}
 */

/**
 * @defgroup command_at_state command at state
 * @{
 */
#define CMD_AT_STATE_FORMAT_CMD         (0u) /*!< 状态-格式化命令 */
#define CMD_AT_STATE_SEND_CMD           (1u) /*!< 状态-命令发送 */
#define CMD_AT_STATE_WAIT_RSP           (2u) /*!< 状态-等待回复 */
#define CMD_AT_STATE_DATA_CHECK         (3u) /*!< 状态-校验回复 */
/**
 * @}
 */

/**
 * @}
 */

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup command_at_global_types command at global types
 * @{
 */

/**
  * @brief  写入数据 / 读取数据
  *
  * @param  data : 写入数据的存储区 / 读取数据的存储区
  *
  * @param  size : 写入的数据大小 / 读取的数据大小 byte
  *
  * @retval 实际写入的数据大小 / 实际读取的数据大小 byte
  */
typedef uint32_t (* cmd_at_rw_fn_t)(void *data, uint32_t size);

/**
  * @brief  at指令 structure definition
  */
typedef struct cmd_at {
    char cmdBuf[CMD_AT_W_BUF_LEN];  /*!< 发送命令数据缓冲区 */
    char dataBuf[CMD_AT_R_BUF_LEN]; /*!< 回复内容数据缓冲区 */
    char head[CMD_AT_MARK_LEN + 1]; /*!< 前缀字符串 */
    char tail[CMD_AT_MARK_LEN + 1]; /*!< 后缀字符串 */
    uint16_t cmdLen;                /*!< 发送命令数据长度 */
    uint16_t dataLen;               /*!< 回复内容数据长度 */
    uint16_t startIndex;            /*!< 起始索引 */
    uint16_t stopIndex;             /*!< 结束索引 */
    uint8_t state : 3;              /*!< 交互状态 @ref command_at_state */
    uint8_t recFlag : 1;            /*!< 接受标志 */
    uint8_t resendTimes;            /*!< 重发次数 */
    uint8_t resendTimesCnt;         /*!< 重发次数计数 */
    uint16_t rspTimeout;            /*!< 回复超时ms */
    uint32_t rspTimeoutCnt;         /*!< 回复超时计数ms */
    cmd_at_rw_fn_t readFn;          /*!< 数据读函数 */
    cmd_at_rw_fn_t writeFn;         /*!< 数据写函数 */
} cmd_at_t;

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup command_at_global_functions
 * @{
 */

void cmd_at_init(cmd_at_t *_at, const char *head, const char *tail, cmd_at_rw_fn_t readFn, cmd_at_rw_fn_t writeFn, uint16_t rspTimeout, uint8_t resendTimes);

uint8_t cmd_at_process_block(cmd_at_t *_at, uint8_t reserve, uint8_t way, const char *ret, const char *cmdFmt, ...);
uint8_t cmd_at_process_poll(cmd_at_t *_at, uint8_t reserve, uint8_t way, const char *ret, const char *cmdFmt, ...);

uint8_t cmd_at_split(cmd_at_t *_at, char *key, char *value, const char *split);
char *cmd_at_rsp_data(cmd_at_t *_at);

/* set/get interface */
void cmd_at_set_rec_flag(cmd_at_t *_at);
uint8_t cmd_at_get_rec_flag(cmd_at_t *_at);
void cmd_at_set_rsp_timeout(cmd_at_t *_at, uint16_t rspTimeout);
uint16_t cmd_at_get_rsp_timeout(cmd_at_t *_at);
void cmd_at_set_resend_times(cmd_at_t *_at, uint8_t resendTimes);
uint8_t cmd_at_get_resend_times(cmd_at_t *_at);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* command_at.h */
